using System;
using System.Web;
using System.Web.SessionState;
using System.DirectoryServices;
using System.Collections;
using System.Text.RegularExpressions;
using System.Data;
using System.Data.SqlClient;
using Mail = System.Web.Mail;
using ActiveDs;
using AMFC.Exceptions;

namespace AMFC
{
	/// <summary>
	/// Summary description for UserObject.
	/// </summary>
	public class UserObject{
		#region ======== Private members =========
		private const string SESSION_KEY = "UserObject";
		private string m_userName;
		private ArrayList m_groups = null;
		private DirectoryEntry m_user;
		HttpContext hc = HttpContext.Current;
		private int m_applID = -1;
		private SQLServer m_db = null;
		#endregion================================
		#region ========= Constructors ===========
		public UserObject():this(Regex.Replace(HttpContext.Current.User.Identity.Name,@".+\\","")){}
		public UserObject(string userName){m_userName=userName;}
		private void InitUser(){
			m_groups = new ArrayList();
			string userPath = Registry.adsRoot/*+Registry.domain+"/"*/+"/"+m_userName+",User";//"LDAP://CN=Administrator,CN=Users,DC=AFCHOME,DC=NET";//
			try{
			if( Registry.adsUser != "" )
				m_user = new DirectoryEntry(userPath,Registry.adsUser,Registry.adsPassword);
			else
				m_user = new DirectoryEntry(userPath);
			IADsMembers groups = (IADsMembers) m_user.Invoke("Groups");
			Regex re = new Regex("^AMFC_WEB_(.+)",RegexOptions.IgnoreCase);
			foreach( IADsGroup g in groups )
				if( re.IsMatch(g.Name) )
					m_groups.Add(re.Match(g.Name).Groups[1].Value);
			}catch(Exception exp){
				throw new Exception("\n\nUserPath: "+userPath+"\n\n",exp);
			}
		}
		#endregion ===============================
		#region ========= Properties =========
		public SQLServer db{
			get{if( m_db == null )m_db = new SQLServer();
					return m_db;
			}
			set{ m_db = value; }
		}
		public ArrayList groups{get{return m_groups;   }}
		public string    group {
			get{if( m_groups == null )InitUser();
					if( m_groups.Count == 0 )throw new NoGroupException(name);
					return m_groups[0].ToString();
			}
		}
		public string		 name {get{return m_userName;}}
		public string		 path {get{return group+"/"+name;}}
		public int			 hasApplID {get{return m_applID > 0?m_applID:0;}}
		public int			 applID{
			get{if( m_applID == 0 )throw new NoApplIDException();
					if( m_applID == -1 )applID = GetApplID();
					return m_applID;
			}
			set{int mid;
				m_applID = value;
				if( m_applID > 0 )mid = menuID;//Check if applicant is accessable
			}
		}
		public int			 menuID{
			get{
				object mid = db.ExecSP("s_MenuID",CallSPMode.Value,applID);
				if( mid == null || (int)mid == 0 )throw new NoMenuIDException(hasApplID);
				return (int)mid;
			}
			set{}
		}
		public SqlDataReader pages{get{return db.Execute("SELECT * FROM v_Menu_Pages WHERE MenuID="+menuID+" ORDER BY TabIndex");}}
		#endregion ===========================
		#region ========= Methods =========
		public DataSet preApproval{get{return db.ExecText("SELECT * FROM vx_PreApprove WHERE ApplicantID=@ApplID",applID);}}
		public DataSet preApproval_BorrowerInfo{get{return (DataSet)db.ExecSP("s_PreApprove_BorrowerInfo",CallSPMode.DataSet,applID);}}
		public byte[] ImageFolder(int folderID){
			return ImageFolder(applID,folderID);
		}
		public byte[] ImageFolder(int applID,int folderID){
			object o = db.ExecuteScalar("SELECT Data FROM t_Image WHERE ApplicantID="+applID+" AND ImageTypeID="+folderID);
			return o==DBNull.Value || o == null?new byte[0]:(byte[])o;
		}
		public void ImageFolder(int folderID,byte[] image){
			ImageFolder(applID,folderID,image);
		}
		public void ImageFolder(int applID,int folderID,byte[] image){
			SqlDataAdapter rAdapter = new SqlDataAdapter("SELECT * FROM t_Image WHERE ApplicantID="+applID+" AND ImageTypeID="+folderID,Registry.dbConnection);
			SqlCommandBuilder cb = new SqlCommandBuilder(rAdapter);
			DataSet rDataSet = new DataSet();
			rAdapter.Fill(rDataSet,"Table");
			// Modify dataSet
			DataTable rTable = rDataSet.Tables["Table"];
			if( rTable.Rows.Count == 0 ){
				db.ExecSP("s_Image_Update",CallSPMode.Nothing,applID,folderID);
				ImageFolder(applID,folderID,image);
				return;
			}
			if( image == null || image.Length == 0 )rTable.Rows[0]["Data"] = DBNull.Value;
			else rTable.Rows[0]["Data"] = image;
			rAdapter.Update(rDataSet, "Table");
			//			db.ExecSP("s_Image_Update",CallSPMode.Nothing,applID,folderID,image);
		}
		public void MailError(Exception exp){
			Mail.MailMessage ml = new Mail.MailMessage();
			ml.BodyFormat = Mail.MailFormat.Html;
			ml.To = AMFC.Registry.mailErrorTo;
			ml.From = AMFC.Registry.mailErrorFrom;
			ml.Subject = exp.Message;
			ml.Body = "<html><body><pre><b>Source:</b>"+exp.Source+
								"\n<b>User:</b>"+name+",<b>ApplicantID:</b>"+hasApplID+
								"\n<b>StackTrace:</b>\n"+exp.StackTrace+"\n<b>TargetSite:</b>\n"+
				exp.TargetSite+"\n"+exp.InnerException+"\n<hr><b>String:</b>\n"+exp.ToString()+"</pre></body></html>";
			Mail.SmtpMail.Send(ml);
		}
		private static int GetApplID(){
			if( HttpContext.Current.Request.QueryString.GetValues("New") != null )
				return AddApplicant();
			string[] appl = HttpContext.Current.Request.QueryString.GetValues("ApplID");
			return appl != null?int.Parse(appl[0]):0;
		}
		public static int AddApplicant(){
			SQLServer db = new SQLServer();
			return (int)db.ExecSP("s_AddApplicant",CallSPMode.Value);
		}
		public static UserObject GetSession(HttpSessionState sessionObject){
			if( sessionObject[SESSION_KEY] == null )
				sessionObject[SESSION_KEY] = new UserObject();
			return (UserObject)sessionObject[SESSION_KEY];
		}
		#endregion ========================
	}
}
